error: `struct A' is inaccessible

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • jheled@gmail.com

    #1

    error: `struct A' is inaccessible


    Staring with g++ 3.4, this code results in an error

    ----------------------------------

    struct A {
    };

    class B : private A {
    };

    class C : public B {
    C(A& a);
    };
    ---------------------------------

    b.cc:2: error: `struct A' is inaccessible
    b.cc:9: error: within this context

    This looks wrong to me. You can't access B as an A, but why C can't use
    the public A independently? what do other
    compliers say?

    (Think of the plausible usage
    ============
    struct A {
    };

    class B : private A {
    public:
    B(A&) {}
    };

    class C : public B {
    C(A& a) : B(a) {}
    };
    ============
    )


    Can someone explain this?

    Thanks, Joseph

  • Andrey Tarasevich

    #2
    Re: error: `struct A' is inaccessible



    jheled@gmail.co m wrote:
    Staring with g++ 3.4, this code results in an error
    >
    ----------------------------------
    >
    struct A {
    };
    >
    class B : private A {
    };
    >
    class C : public B {
    C(A& a);
    };
    ---------------------------------
    >
    b.cc:2: error: `struct A' is inaccessible
    b.cc:9: error: within this context
    >
    This looks wrong to me. You can't access B as an A, but why C can't use
    the public A independently? what do other
    compliers say?
    This is called "class name injection". Every time you define class 'A',
    name 'A' is implicitly inserted ("injected") into the scope of 'A' as a
    public member (see 9/3). In is loosely equivalent to

    class A {
    public:
    typedef ::A A; // (informally, just a sketch)
    ...
    };

    Now, every time you refer to unqualified 'A' inside 'A' or any class
    derived from 'A' directly or indirectly, name lookup will find 'A::A',
    not the global 'A'.

    (Note: an explicit attempt to use 'A::A' in the program will be treated
    as a reference to the constructor, not to the injected class name).

    That's exactly what happens in your case. When you refer to 'A' in
    constructor declaration of 'C', name lookup finds the injected 'A::A',
    which is inaccessible in 'C'.

    You can work around this by using qualified name '::A'

    class C : public B {
    C(::A& a);
    };

    --
    Best regards,
    Andrey Tarasevich

    Comment

    Working...